/*! \file LecteurPhraseAvecArbre.h
 * \brief La spécification de la classe LecteurPhraseAvecArbre
 * \author J. Galavielle, V. Crumière
 * \date 30/12/2011
 * */
#ifndef LECTEURPHRASEAVECARBRE_H_
#define LECTEURPHRASEAVECARBRE_H_

#include "Symbole.h"
#include "LecteurSymbole.h"
#include "TableSymboles.h"
#include "Arbre.h"
#include <string>
#include "ErreurEx.h"

using namespace std;
/*!\class LecteurPhraseAvecArbre
 * \biref La classe représentant la grammaire du langague
 * Cette classe permet de vérifier l'analyse syntaxique du langague
 */
class LecteurPhraseAvecArbre : public ErreurEx {
public:
    /*!\fn LecteurPhraseAvecArbre(string nomFich)
     * \brief Construit un lecteur de phrase    
     * Ce constructeur permet d'interpreter le programme dans le fichier nomFich
     * \param nomFich - nom du Fichier a analyser
     */
    LecteurPhraseAvecArbre(string nomFich); // 

    /*!\fn void analyse()
     * \brief Analyse le programme
     * Si le contenu du fichier est conforme à la grammaire,
     * cette méthode se termine normalement et affiche un message "Syntaxe correcte".
     * La table des symboles (ts) et l'arbre abstrait (arbre) auront été construits
     * Sinon, on affiche les erreurs ainsi que le nombre total d'erreur      
     */
    void analyse(); 

    /*!\fn inline TableSymboles getTs()
     * \brief Retourne la Table des Symboles
     * \return la TableSymboles ts
     */
    inline TableSymboles getTs() {return ts;} 	

    /*!\fn inline void setTableSymboles(TableSymboles table)
     * \brief Affecte la Tables des Symboles
     * Méthode permettant d'affecter la table des symboles courantes par
     * celle passé en paramètre
     * \param table - nouvelle TableSymboles 
     */
    inline void setTableSymboles(TableSymboles table) {this->ts = table;}

    /*!\fn inline Noeud* getArbre()
     * \brief Retourne l'Arbre
     * \return l'Arbre arbre
     */
    inline Noeud* getArbre() {return arbre;} // accesseur

    /*!\fn inline int getNbErreur()
     * \brief Retourne l'entier correspondant au nombre d'erreur dans le programme
     * \return le nombre d'erreur
     */
    inline int getNbErreur() {return this->nbErreur;}

    /*!\var vector<string> generationAda()
     * \brief Tableau des déclarations
     * Tableau contenant l'ensemble des déclarations pour permettre la transformation
     * du code dans le langague Ada.
     */
    vector<string> generationAda();

private:
    /*!/var LeucteurSymbole ls
     * \brief Le lecteur de symboles utilisé pour analyser le fichier
     */
    LecteurSymbole ls;
    /*/var TableSymboles ts
     * \brief La table des symboles valués
     */
    TableSymboles ts;
    /*!\var Noeud* arbre
     * \brief L'arbre abstrait
     */
    Noeud* arbre;
    /*!\var int nbErreur
     * \brief Nombre d'erreur de syntaxe
     */
    int nbErreur;    

    /*!\biref Implémentation de la grammaire*/
    
    /*!\fn  Noeud* programme()
     * \brief Règle d'un programme
     * <programme> ::= debut <seqInst> fin FIN_FICHIER
     */
    Noeud* programme();
    
    /*!\fn  Noeud* seqInst()
     * \brief Règle d'une séquence d'instruction
     * <seqInst> ::= <inst> ; { <inst> ; }
     */
    Noeud* seqInst();
    
    /*!\fn Noeud* inst()
     * \brief Règle d'une instruction
     *  <inst> ::= <affectation> | <instSi> | <instRepeter> | <instLire> |
     * <instEcrire> | <instPour> 
     */
    Noeud* inst();  
    
    /*!\fn Noeud* affectation()
     * \brief Règle d'une affectation
     * <affectation> ::= <variable> = <expression>
     */
    Noeud* affectation(); 
    
    /*!\fn Noeud* expression()
     * \brief Règle d'une expression
     * <expression> ::= <facteur> { <opBinaire> <facteur> }
     */
    Noeud* expression();
    
    /*!\fn Noeud* facteur()
     * \brief Règle d'un facteur
     * <facteur> ::= <entier>  |  <variable>  |  - <facteur>  |  ( <expression> )
     */
    Noeud* facteur();
    
    /*!\fn Noeud* relation()
     * \brief Règle d'une relation
     * <relation> ::= <expression> { <opRel> <relation>}
     */
    Noeud* relation(); 
    
    /*!\fn Noeud* expBool()
     * \brief Règle d'une expression Booléenne
     * <relation> ::= <relation> { <opBool> <relation>}
     */
    Noeud* expBool();
    
    /*!\fn Symbole opRel()
     * \brief Règle d'une opération réelle
     * <opRel> ::= == | != | < | <= | > | >=
     */
    Symbole opRel();
    
    /*!\fn Symbole opUnaire()
     * \brief Règle d'une opération Unaire
     * <opUnaire> ::= - | non
     */
    Symbole opUnaire();
    
    /*!\fn Symbole opEt()
     * \brief Règle d'une opération Et
     *  <opEt> ::= et 
     */
    Symbole opEt(); 
    
    /*!\fn Symbole opOu()
     * \brief Règle d'une opération Ou
     * <opOu> ::= ou
     */
    Symbole opOu();
    
    /*!\fn Noeud* terme()
     * \brief Règle d'un terme
     * <terme> ::= <facteur> { <opMult> <facteur> }
     */
    Noeud* terme();
    
    /*!\fn Symbole opAdd()
     * \brief Règle d'une addition ou soustraction
     * <opAdd>  ::= + | -
     */
    Symbole opAdd();
    
    /*!\fn Symbole opMult()
     * \brief Rèfle d'une multiplication ou division
     * <opMult> ::= *  | /
     */
    Symbole opMult();
    
    /*!\fn Noeud* instSi()
     * \brief Règle de l'instruction si
     * si ( <expBool> ) <seqInst> { sinonsi ( <expBool> ) <seqInst> } [ sinon <seqInst> ] finsi
     */
    Noeud* instSi();
    
    /*!\fn Noeud* instTq()
     * \brief Règle de l'instruction tantque
     * <instTq> ::= tantque ( <expBool> ) <seqInst> fintantque
     */
    Noeud* instTq();
    
    /*!\fn Noeud* instRepeter()
     * \brief Règle de l'instruction repeter
     * repeter <seqInst> jusqua ( <expBool> )
     */
    Noeud* instRepeter();
    
    /*!\fn Noeud* instLire()
     * \brief Règle de l'instruction lire
     * <instLire> ::= lire(<variable>)
     */
    Noeud* instLire();
    
    /*!\fn Noeud* instEcrire()
     * \brief Règle de l'instruction ecrire
     * <instEcrire> ::= ecrire(<expression> | <chaine> )
     */
    Noeud* instEcrire();
    
    /*!\fn Noeud* instPour()
     * \brief Règle de l'instruction pour
     * <instPour> ::= pour(<affectation>;<relation>;<affectation>)
     */
    Noeud* instPour();    

    // outils pour se simplifier l'analyse syntaxique
    /*!\fn void testerSymCour(string ch)
     * \brief Permet de tester le symbole courant
     * si symbole courant != ch, erreur : on léve une exception, sinon rien
     * \param ch - chaine représentant le symbole a tester
     */
    void testerSymCour(string ch);
    /*!\fn void sauterSymCour(string ch)
     * \brief Permet de sauter le symbole courant
     *  si symbole courant == ch, on passe au symbole suivant, sinon on léve une exception
     * \param ch - chaine représentant le symbole a tester
     */
    void sauterSymCour(string ch);
    /*!\fn void erreur(string mess)
     * \brief Affiche un message
     * affiche les message d'erreur mess et léve une exception
     * \param mess - message a afficher
     */
    void erreur(string mess);
};

#endif /* LECTEURPHRASEAVECARBRE_H_ */
